from store import *
from model.me import *
from model.elecom import *
import logging
from datetime import datetime

store = Store()
lock = threading.RLock()  # distributed cilents are all synchronized


def init_client(cfg_path: str = '~/.release.cfg'):
    cfg.load(cfg_path).cfg_chk()
    load_models()


def load_models():
    for d in cfg.rls_models_dir_list:
        for m in Path(d).iterdir():
            tp = model_type(m)
            if tp == 'elecom':
                model = ElecomModel(model_path=m)
            elif tp == 'me':
                model = MeModel(model_path=m)
            else:
                continue
            model.init()
            store.push_model(model)


@io.on(emd_model_state_request)
def on_model_release_state_request(model_list):
    """Manager requests model state.

    Emit `model_release_state_report`,
    data template::

        [
            {
                'name': '<model_name>',
                'state': '<state>'
                'files': '<model_release_files>'
            },
            ...
        ]

    :param model_list:  list of models' name
    """
    with lock:
        io.emit(edm_model_state_report, store.model_state(model_list))


@io.on(emd_model_detail_list_request)
def on_model_detail_list_request(model_list):
    """Manager requests model detail info.

    Emit `model_detail_report`,
    data template::

        [
            {
                'name': '<model_name>',
                'repos_info':
                [
                    {
                        'name': '<repo_name>',
                        'current':  '<branch_name>',
                        'remote': ['<remote_branch_name>', ...]
                    },
                    ...
                ]
            },
            ...
        ]

    :param model_list: list of models' name
    """
    with lock:
        io.emit(edm_model_detail_list_report, store.model_detail_list(model_list))


@io.on(emd_model_start_uploading)
def on_model_upload(upload_data):
    """Manager requests for model uploading

    Request data template::

        {
            'model_name': '<model_name>'
            'file_list':
            [
                {
                    'ftp': '<ftp_path>',
                    'local': '<local_path>'
                    'name': '<file_name>'
                },
                ...
            ]
        },

    :param upload_data:
    """
    with lock:
        store.model_upload(upload_data['model_name'], upload_data['file_list'])


@io.on(emd_model_start_releasing)
def on_model_start_releasing(setting):
    """
    release models in model_list
    :param setting:
    :template:
    ============================================
    {
        'model_name': '<model_name>'
        'make_type': '<make_type_id>'
        'repos_info':
        {
            '<repo_name>': '<branch_name>',
            ...
        },
        'release_info':
        {
            'new_feature': '<new_feature>',
            'bug_fixed': '<bug_fixed>',
            'changed': '<changed>',
            'note': '<note>'
        }
    },
    =============================================

    """
    with lock:
        store.model_release(setting)
        print(f'distributed model start releasing, setting: {setting}')
        print(f'emit model start releasing report.....')
        io.emit(edm_model_start_releasing_report, setting['model_name'])


@io.event
def connect():
    print('Connection established')


@io.event
def disconnect():
    print('Disconnected from server')


if __name__ == '__main__':
    log_filename = datetime.today().isoformat() + '.log'
    logging.basicConfig(filename=log_filename, level=logging.DEBUG)
    logging.info(f'Init log file {log_filename} done.')
    init_client()
    logging.info(f'Init client done.')
    io.connect('http://192.168.96.12:20000', auth={
        'distributed': '1',
        'model_list': store.model_list()
    })
    io.wait()
